package com.heima.gateway.filter;

import com.heima.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;


@Component
@Slf4j
@Order(0)
public class AuthorizeFilter implements GlobalFilter {
    List<String> urlList = Arrays.asList(
            "/v2/api-docs",
            "/login/in"
    );

    /**
     *
     * @param exchange 封装了 请求对象 和 响应对象
     * @param chain 过滤器对象
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求对象 和 相应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 判断当前请求的路径是否需要拦截
        String path = request.getURI().getPath();
        //不需要拦截 直接放行
//        if(path.contains("/login/in")){
//            return  chain.filter(exchange);//如果是登录请求，则不需要拦截
//        }
        for (String url : urlList) {
            if(path.contains(url)){
                return  chain.filter(exchange);
            }
        }
        //获取requset的header中是否包含token
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("token");
        //如果包含 使用jjwt解析taken
        if(StringUtils.isNotBlank(token)){
            try {
                Claims claims = AppJwtUtil.getClaimsBody(token);//获取taken中载荷信息
                int result = AppJwtUtil.verifyToken(claims);
                if(result==-1 || result==0){
                      //登录验证通过
                    Integer id = (Integer) claims.get("id");
                    log.info("用户验证登录成功   当前用户ID ==> {}",id);
                    // 解析成功的话 将解析出的用户id放入请求header中  放行
                     ServerHttpRequest  serverHttpRequest= request.mutate().headers(httpHeaders -> {
                         httpHeaders.add("userId",String.valueOf(id));
                     }).build();
                     exchange=exchange.mutate().request(serverHttpRequest).build();//改变request
                     return chain.filter(exchange);
                }

            } catch (Exception e) {
                e.printStackTrace();
                log.error("验证token信息失败 ===>{}",e.getMessage());
            }
        }

        // 如果token为空 或者 解析失败终止请求
        response.setStatusCode(HttpStatus.UNAUTHORIZED);//返回前端信息 设置响应状态 为未认证
        return response.setComplete(); //直接终止请求

    }
}
